﻿#pragma once
#include "yzrutil.h"
#include "DSP.h"
#include "RingBuffer.h"
#include "array/Arrays.h"

namespace yzrilyzr_dsp{
	ECLASS(RMSCompute, public DSP){
	private:
	RingBufferSample buffer;
	u_sample _rms=0;
	u_sample _rmsSum=0;
	public:
	RMSCompute();
	RMSCompute(u_index bufferSize);
	u_sample procDsp(u_sample v)override{
		u_index cap=buffer.capacity();
		if(cap == 0){
			_rms=0;
			return v;
		}
		u_sample v_sq=v * v;
		_rmsSum-=buffer.oldest();
		_rmsSum+=buffer.newest();
		if(_rmsSum < 0 || isnan(_rmsSum))_rmsSum=0;
		buffer.write(v_sq);
		_rms=sqrt(_rmsSum / cap);
		return v;
	}
	void init(u_sample_rate sampleRate)override{}
	void resetMemory()override{
		_rmsSum=0;
		_rms=0;
		buffer.fill(0);
	}
	void cloneParam(DSP * obj1)override{}
	void setBufferSize(u_index bufferSize){
		buffer.ensureCapacity(bufferSize);
		buffer.fill(0);
	}
	std::shared_ptr<DSP> cloneDSP()override{
		return std::make_shared < RMSCompute>(buffer.capacity());
	}
	u_sample rms()const{
		return _rms;
	}
	yzrilyzr_lang::String toString()const override;
	};
}